package com.ruoyi.business.util;

import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.ruoyi.bizsys.domain.LoanOrder;
import com.ruoyi.common.config.AwsConfig;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.ServerYml;
import com.ruoyi.common.enums.RspEnmu;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.AwsUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.SysFiles;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;

import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
public class PdfUtils {
    public static void main(String[] args) throws IOException {
        String sourceFile = "/Users/jamnsin/OneDrive/Project/MySpace/Work/african-loan/ruoyi-admin/config/template/contract_template.pdf";
        String targetFile = "/Users/jamnsin/Downloads/" + IdUtils.reqId() + ".pdf";

        Map<String, String> map = new HashMap<>();
        map.put("custName", "杨杰");
        map.put("idCard", "4305223243434332");
        map.put("createTime", DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_SLASH));
        map.put("applyNo", "202104206578998279");
        map.put("productNo", "1234567");

        createPDF(map, sourceFile, targetFile);
    }

    /**
     * 使用Map中的参数填充pdf，Map中的key和pdf表单中的field对应
     *
     * @param map
     * @param srcFile
     * @param desFile
     */
    public static void createPDF(Map<String, String> map, String srcFile, String desFile) {
        String path = System.getProperty("user.dir");
        srcFile = File.separator + "config" + File.separator + "template" + File.separator + srcFile;

        PdfReader reader = null;
        PdfStamper stamper = null;
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             FileOutputStream fos = new FileOutputStream(desFile)) {
            //BaseFont base = BaseFont.createFont("/Users/jamnsin/OneDrive/Project/MySpace/Work/african-loan/ruoyi-admin/config/font/SIMKAI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            // BaseFont base = BaseFont.createFont("config/font/SIMKAI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            // BaseFont base = BaseFont.createFont(path + File.separator + "config" + File.separator + "font" + File.separator + "SIMKAI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            BaseFont base = BaseFont.createFont();
            reader = new PdfReader(path + srcFile);
            stamper = new PdfStamper(reader, bos);

            AcroFields acroFields = stamper.getAcroFields();
            acroFields.addSubstitutionFont(base);

            // 1、替换表单元素中的变量为具体的值
            for (Iterator<String> it = acroFields.getFields().keySet().iterator(); it.hasNext(); ) {
                String name = (String) it.next();
                acroFields.setField(name, map.get(name));
                acroFields.setFieldProperty(name, "textfont", base, null);
                acroFields.setFieldProperty(name, "textsize", new Float(15), null);
            }

            // 2、这两步必须有,否则pdf生成失败
            stamper.setFormFlattening(true);
            stamper.close();

            // 生成填充完成的PDF合同文件
            fos.write(bos.toByteArray());
        } catch (FileNotFoundException e) {
            log.error("FileNotFoundException, srcFile = " + srcFile, e);
        } catch (Exception e) {
            log.error("Exception, srcFile = " + srcFile, e);
        } finally {
            if (stamper != null) {
                try {
                    stamper.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                reader.close();
            }
        }
    }

    /**
     * 将File转成FileItem
     *
     * @param file
     * @return
     */
    public static FileItem createFileItem(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }


    /**
     * 创建提现订单合同-pdf
     *
     * @param contractNo
     * @param paramMap
     * @param pdfTemplate
     */
    public static SysFiles createLoanContractPdf(String contractNo, String pdfTemplate, Map paramMap) {
        log.info("创建合同 >>> contractNo = {}, pdfTemplate = {}, paramMap = {}", contractNo, pdfTemplate, paramMap);

        SysFiles sysFile = new SysFiles();
        String tmpPath = RuoYiConfig.getUploadPath() + "/tmp";
        String contractPath = RuoYiConfig.getUploadPath() + "/contract";
        File contractFilePath = new File(contractPath);
        if (!new File(tmpPath).exists()) {
            new File(tmpPath).mkdirs();
        }
        if (!contractFilePath.exists()) {
            contractFilePath.mkdirs();
        }

        log.debug("contractFile：{}", contractPath);

        String contractTmpFilePath = tmpPath + File.separator + contractNo + ".pdf";
        PdfUtils.createPDF(paramMap, pdfTemplate, contractTmpFilePath);
        File contractTmpFile = new File(contractTmpFilePath);
        if (!contractTmpFile.exists()) {
            log.info("合同生成失败");
            throw new BusinessException(RspEnmu.CONTRAC_GENERATE_ERR);
        }
        try {
            if (("PRO").equals(ServerYml.getRunEnv())) {
                log.info("ServerYml.getRunEnv()):" + ServerYml.getRunEnv());
                //上传到AWS对象桶
                log.info("contractTmpFile:" + contractTmpFile.getPath());
                //获取当前时间
                Date date = new Date();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
                String key = AwsConfig.getPdfPath() + dateFormat.format(date);
                log.info("key:" + key);
                URL url = AwsUtil.uploadObject(AwsConfig.getBucketName(), key + "/" + contractTmpFile.getName(), contractTmpFile.getPath());
                //String fileName = FileUploadUtils.upload(contractPath, FileUtils.fileToMultipartFile(contractTmpFile));
                log.debug("合同地址：{}", url);

                sysFile.setMediaId(contractNo);
                //sysFile.setUrl(fileName);
                sysFile.setAwsS3Url(String.valueOf(url));
            } else {
                log.info("ServerYml.getRunEnv()):" + ServerYml.getRunEnv());
                String fileName = FileUploadUtils.upload(contractPath, FileUtils.fileToMultipartFile(contractTmpFile));
                log.debug("合同地址：{}", fileName);
                sysFile.setMediaId(contractNo);
                sysFile.setUrl(fileName);
            }

        } catch (IOException e) {
            log.error("合同上传异常", e);
            throw new BusinessException(RspEnmu.CONTRAC_GENERATE_ERR);
        }

        try {
            if (contractTmpFile.exists()) {
                contractTmpFile.delete();
            }
        } catch (Exception e) {
            log.error("删除合同临时文件异常，{}", e);
        }

        return sysFile;
    }

}